home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
422_02
/
misc
/
longcalc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-20
|
4KB
|
157 lines
/*
* This program implements a simple "calculator" using LONG numbers.
* It demonstrates the "long" math functions from the library.
*
* Copyright 1994 Dave Dunfield
* All rights reserved.
*
* Permission granted for personal (non-commercial) use only.
*
* Compile command: cc longcalc -fop
*/
#include <stdio.h>
#include <window.h>
/*
* Default LONG number size is 4 bytes (32 bits). If you wish to change
* this (up to 256 bits), edit the 'LSIZE EQU 4' in the LONGMATH.ASM
* file in the library. You also have to adjust the sizes of all array
* declarations which are to contain LONG numbers. For this demo,
* just adjust the constant defined below.
*/
#define LSIZE 4 /* 32 bit numbers */
/*
* Long number registers
*/
char reg[LSIZE], temp1[LSIZE], temp2[LSIZE];
/*
* Input/Output Digit buffer. Note that we use an approximation to
* compute the number of digits required based on the size of the
* LONG numbers.
*/
char buffer[(LSIZE*25)/10+1];
/*
* This temporary variable used by the LONGMATH functions is useful,
* because it will contain the remainder after a division.
*/
extern char Longreg[];
/*
* Convert a LONG number into a printable string
*/
long_to_string(string, n1, base)
unsigned char *string, *n1, base;
{
unsigned sp;
unsigned char c, stack[(LSIZE*25)/10+1];
longcpy(temp2, n1);
longset(temp1, base);
/* Stack up digits in reverse order */
sp = 0;
do {
longdiv(temp2, temp1);
stack[sp++] = ((c = *Longreg) > 9) ? c + '7' : c + '0'; }
while(longtst(temp2));
/* Unstack digits into output buffer */
do
*string++ = stack[--sp];
while(sp);
*string = 0;
}
/*
* Convert a string into a LONG number
* Returns character terminating conversion.
*/
string_to_long(string, n1, base)
unsigned char *string, *n1, base;
{
unsigned char c;
longset(n1, 0);
while(c = *string++) {
if(isdigit(c))
c -= '0';
else if(c >= 'a')
c -= ('a' - 10);
else if(c >= 'A')
c -= ('A' - 10);
else
break;
if(c >= base)
break;
longset(temp1, base);
longmul(n1, temp1);
longset(temp1, c);
longadd(n1, temp1); }
return c;
}
/*
* Main calculator program
*/
main()
{
unsigned char c, op;
char *ptr;
wopen(0, 0, 80, 25, WSAVE|WCOPEN|WBOX1|WWRAP|WSCROLL|NORMAL);
wputs("Long Number Calculator, Supports: + - * / % = ENTER(clear) ESC(exit)\n");
clear: /* Clear the calculator by forcing a copy operation */
wputs("Clear\n");
op = '=';
ptr = buffer; /* Begin processing a number */
for(;;) { /* Continue processing a number */
while(isdigit(c = wgetc())) { /* Collect digits into string */
wputc(c);
*ptr++ = c; }
*ptr = 0; /* Zero terminate */
string_to_long(buffer, temp2, 10); /* Get LONG value for operation */
switch(op) { /* Perform pending operation */
case '=' : longcpy(reg, temp2); break;
case '+' : longadd(reg, temp2); break;
case '-' : longsub(reg, temp2); break;
case '*' : longmul(reg, temp2); break;
case '/' : longdiv(reg, temp2); break;
case '%' : longdiv(reg, temp2); longcpy(reg, Longreg); }
operate: /* Process next operator */
wputc(c); /* Echo next command */
switch(c) {
case 0x1B: /* Exit */
wclose();
return;
default: /* Unrecognized */
wputs(" ?Invalid input... ");
case '\n' : /* Clear */
goto clear;
case '=' : /* Display results */
long_to_string(buffer, reg, 10);
wputs(buffer);
if(!isdigit(c = wgetc())) /* Chained operation */
goto operate;
wputc('\n');
wputc(c);
op = '=';
ptr = buffer;
*ptr++ = c;
continue;
case '+' : /* Addition */
case '-' : /* Subtraction */
case '*' : /* Multiplication */
case '/' : /* Division */
case '%' : /* Modulus */
op = c; }
ptr = buffer; } /* Reset number pointer */
}